package com.zone.lib.download.execute;

import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.zone.lib.download.DownloadStatus;
import com.zone.lib.download.bean.DownloadInfo;
import com.zone.lib.download.db.entity.Download;
import com.zone.lib.download.utils.AppStatusUpdateNotify;
import com.zone.lib.download.utils.LogUtils;
import com.zone.lib.download.utils.SharedPreferencesUtil;
import com.zone.sdk.common.http.callback.ResultCallBack;
import com.zone.sdk_api.ApiManager;
import com.zone.sdk_api.common.Content;
import com.zone.vehicle.sdk.module.superapp.request.AppsDownloadRequest;

import org.apache.commons.lang3.ObjectUtils;
import org.jetbrains.annotations.NotNull;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;

import okhttp3.ResponseBody;

public class DownloadTask implements Runnable {

    public static final String TAG = DownloadTask.class.getSimpleName();

    private Context context;
    private DownloadInfo info;
//    private FileInfo mDownload;
    private Download mDownload;
    //    private DbHolder dbHolder;
    private boolean isPause;

    public DownloadTask(Context context, DownloadInfo info
//            , DbHolder dbHolder
    ) {
        this.context = context;
        this.info = info;
//        this.dbHolder = dbHolder;

        //初始化下载文件信息
//        mDownload = new FileInfo();
//        mDownload.setCode(info.getCode());
////        mDownload.setId(info.getUniqueId());
//        mDownload.setDownloadUrl(info.getUrl());
//        mDownload.setFilePath(info.getFile().getAbsolutePath());

        mDownload = info.getDownload();
//        mDownload.setCode(info.getCode());
//        mDownload.setDownloadStatus(DownloadStatus.PAUSE_DOWNLOAD);
//        mDownload.setDownloadUrl(info.getAppUrl());
//        mDownload.setFilePath(info.getFile().getAbsolutePath());

//        LogUtils.i(TAG, "构造函数 -> 初始化 mDownload=" + mDownload);

//        FileInfo fileInfoFromDb = dbHolder.getFileInfo(info.getUniqueId());
//        Download download = DownloadDaoUtilsStore.getInstance().getDownloadByCode(info.getCode());
        long location = 0;
        long fileSize = 0;
        if (mDownload != null) {
            location = mDownload.getDownloadLocation();
            fileSize = mDownload.getSize();

            if (location == 0) {
                if (info.getFile().exists()) {
                    info.getFile().delete();
                }
            } else {
                //因为未知的原因, 这个文件不存在了,(虽然数据库记录表明我们的确已经下载过了),所以我们要从头开始
                if (!info.getFile().exists()) {
                    LogUtils.i(TAG, "file = " + info.getFile());
                    Log.i(TAG, "数据库记录表明我们下载过该文件, 但是现在该文件不存在,所以从头开始");
//                    dbHolder.deleteFileInfo(info.getUniqueId());
//                    DownloadDaoUtilsStore.getInstance().getDownloadAppDaoUtils().delete(download);
                    location = 0;
                    fileSize = 0;
                }
            }
        } else {
            if (info.getFile().exists()) {
                info.getFile().delete();
            }
        }
//        mDownload.setSize(fileSize);
//        mDownload.setDownloadLocation(location);
        mDownload.setSize(fileSize);
        mDownload.setDownloadLocation(location);
//        LogUtils.i(TAG, "构造函数() -> 初始化完毕  mDownload=" + mDownload);
    }

    @Override
    public void run() {
//        downloadOkhttp();
        downloadHttp();
    }

    public void pause() {
        isPause = true;
    }

    public void restart() {
        isPause = false;
    }

    public int getStatus() {
        if (null != mDownload) {
            return mDownload.getDownloadStatus();
        }
        return DownloadStatus.FAIL_DOWNLOAD;
    }

    public void setFileStatus(int status) {
        mDownload.setDownloadStatus(status);
    }

    public void sendBroadcast(Intent intent) {
        context.sendBroadcast(intent);
    }

    public DownloadInfo getDownLoadInfo() {
        return info;
    }

    public Download getDownload() {
        return mDownload;
    }

    private void downloadOkhttp(){
        if (ObjectUtils.isNotEmpty(mDownload)){
            LogUtils.i(TAG, "准备开始下载");
            mDownload.setDownloadStatus(DownloadStatus.PREPARE_DOWNLOAD);
            mDownload.setCreateTime(new Date().toString());
            AppStatusUpdateNotify.appNotify(context, info, mDownload);

            AppsDownloadRequest request = getAppsDownloadRequest();
            try {
                RandomAccessFile accessFile = new RandomAccessFile(info.getFile(), "rwd");
                accessFile.seek(mDownload.getDownloadLocation());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


            ApiManager.getInstance().appsDownload(request, new ResultCallBack<ResponseBody>() {
                @Override
                public void onSuccess(ResponseBody responseBody) {
                    LogUtils.i(TAG, "appsDownload onSuccess");
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            download(responseBody);
                        }
                    }).start();

                }

                @Override
                public void onError(String errorCode, String message) {
                    LogUtils.i(TAG, "onError errorCode"+errorCode+" message="+message);
                }

                @Override
                public void onComplete() {

                }
            });
        }
    }

    @NotNull
    private AppsDownloadRequest getAppsDownloadRequest() {
        AppsDownloadRequest request = new AppsDownloadRequest();
        request.setType(mDownload.getAppType());
        request.setAppCode(mDownload.getCode());
        if (mDownload.getDownloadLocation() == 0){
            request.setMode("0");
            request.setPoint("0");
        }else if (mDownload.getDownloadStatus() == DownloadStatus.PAUSE_DOWNLOAD){
            request.setMode("1");
            request.setPoint(String.valueOf(mDownload.getDownloadLocation()));
        }
        request.setUserId(SharedPreferencesUtil.getInstance(context).getSP(Content.USER_ID));
        request.setVin(SharedPreferencesUtil.getInstance(context).getSP(Content.VIN));
        LogUtils.i(TAG, "request="+ JSON.toJSONString(request));
        return request;
    }

    private void download(ResponseBody responseBody){

        InputStream is = null;
        FileOutputStream fos = null;
        mDownload.setDownloadStatus(DownloadStatus.LOADING_DOWNLOAD);
        AppStatusUpdateNotify.appNotify(context, info, mDownload);

        try {
            File dir = new File(context.getCacheDir(), "download");
            if (!dir.exists()){
                dir.mkdirs();
            }
            File saveFile = new File(dir, mDownload.getCode()+".apk");
            long total = responseBody.contentLength();
            mDownload.setTotal(total);
            mDownload.setSize(total);
            Log.e(TAG, "total------>" + total);
            is = responseBody.byteStream();
            fos = new FileOutputStream(saveFile);
            byte[] buffer = new byte[1024 * 8];
            int offset;
//                        RandomAccessFile accessFile = new RandomAccessFile(info.getFile(), "rwd");
//                        accessFile.seek(mDownload.getDownloadLocation());
            long millis = SystemClock.uptimeMillis();
            while ((offset = is.read(buffer)) != -1) {
                if (isPause) {
                    LogUtils.i(TAG, "下载过程 设置了 暂停");
                    mDownload.setDownloadStatus(DownloadStatus.PAUSE_DOWNLOAD);
                    isPause = false;
                    AppStatusUpdateNotify.appNotify(context, info, mDownload);
                    return;
                }
                // TODO
//                            accessFile.write(buffer, 0, offset);
                mDownload.setDownloadLocation(mDownload.getDownloadLocation() + offset);
                mDownload.setDownloadStatus(DownloadStatus.LOADING_DOWNLOAD);
//                if (SystemClock.uptimeMillis() - millis >= 1000) {
//                    millis = SystemClock.uptimeMillis();
//                    AppStatusUpdateNotify.appNotify(context, info, mDownload);
//                }
                    AppStatusUpdateNotify.appNotify(context, info, mDownload);
            }
            mDownload.setDownloadStatus(DownloadStatus.COMPLETE_DOWNLOAD);
            AppStatusUpdateNotify.appNotify(context, info, mDownload);
        } catch (IOException e) {
            Log.e("download", e.toString());
            mDownload.setDownloadStatus(DownloadStatus.FAIL_DOWNLOAD);
            AppStatusUpdateNotify.appNotify(context, info, mDownload);
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                Log.e("download", e.toString());
            }
        }
    }


    private void downloadHttp(){

        if (ObjectUtils.isNotEmpty(mDownload)){
            LogUtils.i(TAG, "准备开始下载");
            mDownload.setDownloadStatus(DownloadStatus.PREPARE_DOWNLOAD);
            mDownload.setCreateTime(new Date().toString());
            AppStatusUpdateNotify.appNotify(context, info, mDownload);

            AppsDownloadRequest request = getAppsDownloadRequest();
            try {
                RandomAccessFile accessFile = new RandomAccessFile(info.getFile(), "rwd");
                accessFile.seek(mDownload.getDownloadLocation());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


                try {

                    File dir = new File(context.getCacheDir(), "download");
                    if (!dir.exists()){
                        dir.mkdirs();
                    }
                    File saveFile = new File(dir, mDownload.getCode()+".apk");

                    URL url = new URL("http://acp.z-onesoftware.com/aps/apps/download");
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

                    // 设置通用的请求属性  conn.setRequestProperty("accept", "*/*");
                    conn.setRequestProperty("connection", "Keep-Alive");
                    conn.setRequestMethod("POST");
                    conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
                    conn.setRequestProperty("Accept", "application/json");
                    conn.setUseCaches(false);
                    // 发送POST请求必须设置以下两行  conn.setDoOutput(true);
                    conn.setDoInput(true);
                    conn.setReadTimeout(3000);
                    conn.setConnectTimeout(3000);

                    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
//                    Gson gson = new Gson();
//                    String jsonString = gson.toJson(request);
                    wr.writeBytes(JSON.toJSONString(request));
                    wr.flush();
                    wr.close();

                    InputStream inputStream = conn.getInputStream();

                    FileOutputStream fileOutput = new FileOutputStream(saveFile);
//                    byte[] buf = new byte[1024];//分配byte  double count = 0;
                    int fileLength = conn.getContentLength();
                    mDownload.setTotal(fileLength);
                    mDownload.setSize(fileLength);
                    if (conn.getResponseCode() >= 400) {
//                        Toast.makeText(activity.getApplicationContext(), "链接超时", Toast.LENGTH_SHORT).show();
                    } else {
                        byte data[] = new byte[4096];
                        long total = 0;
                        int count;
//                        ByteArrayOutputStream output = new ByteArrayOutputStream();
                        long millis = SystemClock.uptimeMillis();
                        while ((count = inputStream.read(data)) != -1) {
                            if (isPause) {
                                LogUtils.i(TAG, "下载过程 设置了 暂停");
                                mDownload.setDownloadStatus(DownloadStatus.PAUSE_DOWNLOAD);
                                isPause = false;
                                AppStatusUpdateNotify.appNotify(context, info, mDownload);
                                return;
                            }
                            total += count;
                            // publishing the progress....
                            if (fileLength > 0 ) {
//                            handler.sendEmptyMessage(((int) (total * 100 / fileLength)) - 1);
                                mDownload.setDownloadLocation(total);
                                mDownload.setDownloadStatus(DownloadStatus.LOADING_DOWNLOAD);
                                if (SystemClock.uptimeMillis() - millis >= 1000) {
                                    millis = SystemClock.uptimeMillis();
                                    AppStatusUpdateNotify.appNotify(context, info, mDownload);
                                }
                            }
                            //TODO
//                            AppStatusUpdateNotify.appNotify(context, info, mDownload);
                            fileOutput.write(data, 0, count);
                        }
                        mDownload.setDownloadStatus(DownloadStatus.COMPLETE_DOWNLOAD);
                        AppStatusUpdateNotify.appNotify(context, info, mDownload);
                    }
                    conn.disconnect();//须要记得关闭链接  fileOutput.close();
                    inputStream.close();
                } catch (Exception e) {
                    mDownload.setDownloadStatus(DownloadStatus.FAIL_DOWNLOAD);
                    AppStatusUpdateNotify.appNotify(context, info, mDownload);
                    e.printStackTrace();
                    throw new RuntimeException("下载失败...");
                }
        }
    }

    /**
     * map转url参数
     */
    public static String map2Url(Map<String, String> paramToMap) {
        if (null == paramToMap || paramToMap.isEmpty()) {
            return null;
        }
        StringBuffer url    = new StringBuffer();
        boolean      isfist = true;
        for (Map.Entry<String, String> entry : paramToMap.entrySet()) {
            if (isfist) {
                isfist = false;
            } else {
                url.append("&");
            }
            url.append(entry.getKey()).append("=");
            String value = entry.getValue();
            if (!TextUtils.isEmpty(value)) {
                try {
                    url.append(URLEncoder.encode(value, "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
        return url.toString();
    }



}
